#include "aerial\Game\GameObject\FlyObject\Commander.h"

#include "aerial\Game\GameObject\Equipment\Shield.h"
#include "aerial\Game\GameObject\Equipment\Propeller.h"

#include <iostream>

using namespace std;

const float Commander::SpeedPowerGen = 2.f;
const float Commander::MaxArmor = 70.f;
const float Commander::MaxPower = 120.f;

const float Commander::MaxShieldRadius = 4.5f;
const float Commander::RadiusPS = M_PI;
const float Commander::MPPS = 300.f;

Commander::Commander(int id, const char* username, float x, float y, uchar side, float A)
	: FlyObject(x, y, A, id, username, side), countDt(0),turnSide(0),rotateSide(0),
	lastArmor(armor),judge(0),judgeWudi(0),countWudi(0),typeWudi(0){
		power = MaxPower;
		armor = MaxArmor;

		b2CircleShape circle;
		circle.m_radius = 1.5f;

		b2FixtureDef fixtureDef;
		fixtureDef.shape = &circle;
		fixtureDef.density = 1.f;
		fixtureDef.friction = 1.f;
		fixtureDef.restitution = 0.1f;

		body->SetLinearDamping(1.f);

		body->CreateFixture(&fixtureDef);

		shield = new Shield(MaxShieldRadius, this);
		spr = hgeResMan->GetSprite("spr.commander");
		propeller = new Propeller(this, 10.f, 60.f);
}

Commander::~Commander() {}

void Commander::render()
{
	if (!toDestroy) {
		if (typeWudi)
			spr->SetColor(0xff0000ff);
		else
		{
			if (judge)
				spr->SetColor(0xffff0000);
			else
				spr->SetColor(0xffffffff);
		}
		spr->RenderEx(T.x, T.y, A, 0.5f, 0.5f);
		shield->renderShield(T.x, T.y);
		propeller->rendPropeller();
	}
	if (side != MeSide)	fnt->SetColor(0xffff0000);
	else fnt->SetColor(0xffffffff);
	fnt->printf(T.x, T.y, HGETEXT_LEFT, "%s", username);
}

bool Commander::update(float dt)
{
	// power regeneration
	power += SpeedPowerGen * dt;
	if (power > MaxPower) power = MaxPower;

	move(dt);	// action move
	turn(dt);	// action rotate

	lastArmor = armor;
	// flyobject dealing with general equipment and network deviation
	FlyObject::update(dt);
	return false;
}

void Commander::move(float dt)
{
	int j = status & F_M_WUDI;
	if (j)
	{
		if (power > 110) 
		{
			power -= 110.f;
			typeWudi = 1;
		}
	}
	if ( typeWudi == 1)
	{
		countWudi++;
		if (countWudi < 500) armor = lastArmor;
		else
		{
			countWudi = 0;
			typeWudi = 0;
		}

	}
	else
	{
		if (lastArmor != armor)
			judge = 1;
		else
			judge = 0;;
	}

	int m = status & F_M_MOV;
	int x = status & F_V_CROT;
	int y = status & F_V_CCROT;
	if (m && turnSide == 0 && !x && !y) 
	{
		b2Vec2 vD(
			GetDirection().x * MPPS / BattleHelper::getRatio(), 
			GetDirection().y * MPPS / BattleHelper::getRatio()
			);
		SetSpeed(vD);
	}
}

void Commander::turn(float dt)
{
	int r = status & (F_M_ROT);
	if (r == F_V_CROT) 
	{
		if (countDt != 0 && turnSide!=1 )
			--countDt;
		turnSide = 1;
	}
	else if (r == F_V_CCROT) 
	{
		if (countDt != 0 && turnSide!=2 )
			countDt++;
		turnSide = 2;
	}

	if (turnSide == 1)
	{
		countDt += 1;
		if( countDt != 11 && countDt != 0)
		{
			Rotate(RadiusPS * 0.05f);
		}
		else
		{
			if (countDt != 0)
				rotateSide++;
			rotateSide = rotateSide % 4;
			SetRotate(rotateSide * b2_pi / 2.f);
			turnSide = 0;
			countDt = 0;
		}
	}

	else if (turnSide == 2)
	{
		countDt -= 1;
		if( countDt != -11 && countDt != 0)
		{
			Rotate(-RadiusPS * 0.05f);
		}
		else
		{
			if (countDt != 0)
				rotateSide--;
			rotateSide = rotateSide % 4;
			SetRotate(rotateSide * b2_pi / 2.f);
			turnSide = 0;
			countDt = 0;
		}
	}
	status &= ~F_M_ROT;
	//SetState(0, F_M_ROT);
}

void Commander::processInput()
{
	float offsetX, offsetY;
	if ( T.x < 400 ) offsetX = 0.f;
	else if ( T.x < 3440 ) offsetX = T.x - 400.f;
	else offsetX = 3040.f;

	if (T.y < 300) offsetY = 0.f;
	else if (T.y < 780) offsetY = T.y - 300.f;
	else offsetY = 480.f;

	hge->Input_GetMousePos(&lastX, &lastY);
	lastX += offsetX;
	lastY += offsetY;
	while (hge->Input_GetEvent(inputEvent))
	{
		switch (inputEvent->key)
		{
		case HGEK_A:
			if (inputEvent->type != INPUT_KEYDOWN) 
			{
				SetState(0, F_M_MOV);
				SetState(F_V_CCROT, F_M_ROT);
			}
			//else SetState(0, F_V_CCROT);
			break;
		case HGEK_D:
			if (inputEvent->type != INPUT_KEYDOWN) 
			{
				SetState(0, F_M_MOV);
				SetState(F_V_CROT, F_M_ROT);
			}
			//else SetState(0, F_V_CROT);
			break;
		case HGEK_W:
			if (inputEvent->type == INPUT_KEYDOWN) SetState(F_M_MOV, F_M_MOV); 
			else SetState(0, F_M_MOV);
			break;
		case HGEK_RBUTTON:
			if (Shield::available(this)) {
				if (inputEvent->type == INPUT_MBUTTONDOWN) SetState(M_SHIELD, M_SHIELD);
				else SetState(0, M_SHIELD);
			}
		case HGEK_Q:
			if (inputEvent->type == INPUT_KEYDOWN) SetState(F_M_WUDI, F_M_WUDI);
			else SetState(0, F_M_WUDI);
			break;
		}
	}
}
